
Skt.Editor = L.Class.extend({
	
	includes: L.Mixin.Events,
	
	events: ['editingEnabledChanged','toolChanged','canvasesUpdated','currentCanvasChanged','canvasChanged'],
	
	initialize: function(sketchpad, options) {
		L.Util.setOptions(this, options);
		
		this._editingEnabled = true;
		if ( typeof this.options.editingEnabled !== 'undefined' )
			this._editingEnabled = this.options.editingEnabled;
		
		this._sketchpad = sketchpad;
		
		this._tool = new Skt.NullTool();
		this._toolOptions = new Skt.ToolOptions();
		
		//canvas activo
		this._canvas = null;
		
		//canvases disponibles
		this._canvases = {};
		
		// copy-paste vars
		this._copy_paste_dx = 0;
		this._selectedElements = null;
		
		this._deleteAction = false;
	},
	
	addCanvasFromRoom: function (room, options) {
		options = options || {};
		options.width = 1024;
		options.height = 672;
		options.scale = 1.0;

		var canvas = new Skt.Canvas(room, options);
		canvas.scale(0.1, false);
		
		this._canvases[room.getId()] = canvas;
		
		canvas.on('change', this._canvasChanged, this);
		
		this.fire('canvasesUpdated', {
			action: 'addCanvas',
			canvas: canvas,
			editor: this
		});
		
	},
	
	removeCanvasFromRoom: function (room) {
		var canvas = this._canvases[room.getId()];
		delete this._canvases[room.getId()];
		
		this.fire('canvasesUpdated',{
			action: 'removeCanvas',
			canvas: canvas,
			editor: this
		});
	},
	
	setCurrentCanvas: function(roomId) {
		var currentCanvas = this.getCurrentCanvas();
		var newCanvas = this.findCanvas(roomId);

		if (currentCanvas != null) {
			if (currentCanvas.getRoom().getId() == roomId) {
				console.log("[WARNING] Skt.Editor.setCurrentCanvas: new and old canvas are the same");
				return;
			}
			this._tool.disable();
			currentCanvas.scale(0.1, false);
			currentCanvas.onRemove(this);
		}

		this._canvas = newCanvas;
		if ( this._canvas != null ) {
			this._canvas.scale(1.0);
			this._canvas.onAdd(this);
			this._tool.enable(this);
		}
		
		this.fire("currentCanvasChanged", {
			newCanvas: this._canvas,
			oldCanvas: currentCanvas,
			editor: this
		});

	},
	
	isCurrentCanvas: function(canvas) {
		return this.getCurrentCanvas() != null
			&& this.getCurrentCanvas().getRoom().getId() == canvas.getRoom().getId();
	},
	
	setTool: function(tool) {
		if (tool instanceof Skt.Tool) {
			// finalizar la herramienta anterior
			this._tool.disable();  
			this._tool = tool;
			this._tool.enable(this);
			
			this.fire('toolChanged', {
				tool: this._tool,
				editor: this
			});
		}
	},
	
	setToolOptions: function(value) {
		for ( var key in value )
			this._toolOptions[key](value[key]);

		if ( this._tool instanceof Skt.SelectTool ) {
			var elements = this._tool.getSelection();
			var color = this._toolOptions.color();
			var opacity = this._toolOptions.opacity();
			var width = this._toolOptions.width() * this.scale();

			for ( var n = elements.length; n--; ) {
				var type = elements[n]._attrs.type;
				if ( type == 'text' ) {
					elements[n].attr({
						"fill": color,
					});
				} else if( type == 'path' ) {
					elements[n].attr({
						"stroke": color,
						"stroke-opacity": opacity,
						"stroke-width": width,          
					});
				}
			}   
		}

		return this;
	},
	
	setEditingEnabled: function(enabled) {
		this._editingEnabled = enabled;
		this.fire('editingEnabledChanged', {
			enabled: enabled,
			editor: this
		});
	},
	
	scale: function(value, center) {
		if ( this.getCurrentCanvas() != null )
			return this.getCurrentCanvas().scale(value, center);
		else
			return null;
	},

	undoAvailable: function() {
		if ( !this.getCurrentCanvas() ) return false;
		return this.getCurrentCanvas().getRoom().getHistory().undoable();
	},

	undo: function() {
		if ( !this.getCurrentCanvas() ) return;
		
		//quitar seleccion para evitar problemas
		if ( this._tool instanceof Skt.SelectTool )
			this._tool.setSelection([]);

		this.getCurrentCanvas().getRoom().getHistory().undo();
	},

	redoAvailable: function() {
		if ( !this.getCurrentCanvas() ) return false;
		return this.getCurrentCanvas().getRoom().getHistory().redoable();
	},

	redo: function() {
		if( !this.getCurrentCanvas() ) return;

		//quitar seleccion para evitar problemas
		if(this._tool instanceof Skt.SelectTool)
			this._tool.setSelection([]);

		this.getCurrentCanvas().getRoom().getHistory().redo();
		return this; // function-chaining
	},

	clear: function() {
		if( this.getCurrentCanvas() != null ) {
			this.getCurrentCanvas().clearElements();
		}
	},
	
	canCopy: function() {
		return this._tool instanceof Skt.SelectTool && this._tool.getSelection().length > 0;
	},
	
	canPaste: function() {
		return this._selectedElements != null;
	},
	
	copy: function() {
		if ( this.canCopy() ) {
			//se restablece la distancia de desplazamiento
			this._copy_paste_dx = 0;
			this._selectedElements = this._tool.getSelection();
		}  
	},

	paste: function() {
		if ( !this.canPaste() )
			return;

		var elements = this._selectedElements;
		var copies = [];
		var canvas = this._canvas;
		var dx = this._copy_paste_dx += 20;

		for ( var i = 0, len = elements.length; i < len; i++ ) {
			var el = elements[i];
			var s = el.serialize();
			uniqueId(s, true);
			var cp = Skt.ElementFactory.getElement(s);
			canvas.addElement(cp);
			//la referencia cambia, no se agrego el objeto sino una copia
			cp = canvas.getElement(cp.id);
			cp.move(dx, dx);
			copies.push(cp);
		}

		this.setTool(new Skt.SelectTool(this));
		this._tool.setSelection(copies);
	},
	
	removeSelectedElements: function() {
		if (this._tool instanceof Skt.SelectTool) {
			var selection = this._tool.getSelection();
			this._tool.emptySelection();

			var canvas = this.getCurrentCanvas();
			for (var i=0, len=selection.length; i<len; i++)     
				canvas.removeElement(selection[i].id);
		} 
	},
	
	toggleDeleteAction: function() {
		this.setDeleteAction( !this._deleteAction );
	},
	
	setDeleteAction: function(bool) {
		this._deleteAction = bool;
	},
	
	getCanvas: function(roomId) {
		if ( this._canvases.hasOwnProperty(roomId) )
			return this._canvases[roomId];
		return null;
	},
	
	findCanvas: function(roomId) {
		return this.getCanvas(roomId);
	},
	
	getCurrentRoomId: function() {
		if ( this.getCurrentCanvas() != null )
			return this.getCurrentCanvas().getRoom().getId();
		return null;
	},
	
	getCurrentCanvas: function() { return this._canvas; },
	getCanvases: function() { return this._canvases; },
	getOptions: function() { return this.options; },
	isEditingEnabled: function() { return this._editingEnabled; },
	isDeleteAction: function() { return this._deleteAction; },
	getTool: function() { return this._tool; },
	getToolOptions: function() { return this._toolOptions; },
	getSketchpad: function() { return this._sketchpad; },
	
	_canvasChanged: function(params) { this.fire('canvasChanged', params); }
	
});



Skt.Editor.findSelf = function(editor) {
	return Skt.sketchpad.getEditor();
};
